package main

import (
	"encoding/json"
	"fmt"
	"github.com/gorilla/mux"
	"io/ioutil"
	"log"
	"net/http"
)

type UsersInfo struct {
	Usersinfo []UserInfo `json:"users"`
}

type UserInfo struct {
	UserId int `json:"userid"`
	UserName string `json:"username"`
	UserAge int `json:"userage""`
}

var usersinfo UsersInfo

type AuthUser struct {
	Name     string `json:"name"`
	Password string `json:"password"`
}

var Users = make(map[string]AuthUser)

func main() {
	usersinfo.Usersinfo = append(usersinfo.Usersinfo,UserInfo{0,"小赵",22})
	usersinfo.Usersinfo = append(usersinfo.Usersinfo,UserInfo{2,"小钱",32})
	usersinfo.Usersinfo = append(usersinfo.Usersinfo,UserInfo{3,"小孙",14})
	usersinfo.Usersinfo = append(usersinfo.Usersinfo,UserInfo{4,"小李",23})

	var serverport string = "8000"
	//打印log
	log.Println("server is listen on 0.0.0.0:8000")
	r := mux.NewRouter()
	s := r.PathPrefix("/api").Subrouter()

	//get user info
	s.HandleFunc("/GETUserPassword", GETUsrInfo).Methods("GET")

	//auth user
	s.HandleFunc("/AUTHUser", AUTHuser_urlargs) //axios 默认参数请求，默认为get方式。定义的方法为post好象没起作用。

	//set user info
	s.HandleFunc("/SETUserPassword_url_args", SETUserInfo_urlargs).Methods("GET")
	s.HandleFunc("/SETUserPassword_Form_data", SETUserInfo_bodykv).Methods("POST")
	s.HandleFunc("/SETUserPassword_json", SETUserInfo_bodyjson).Methods("POST")

	s.HandleFunc("/mock_userdata", Mockuser)
	//server开始监听
	err := http.ListenAndServe(":"+serverport, r)
	if err != nil {
		fmt.Println(err)
		return
	}
}
func Mockuser(w http.ResponseWriter, r *http.Request)  {
	CrossDomain(w, r)
	usesjson,err :=  json.Marshal(usersinfo)
	if err != nil {
		fmt.Println(err)
	}

	w.Write(usesjson)
}

func AUTHuser_urlargs(w http.ResponseWriter, r *http.Request) {
	CrossDomain(w, r)
	err := r.ParseForm()
	if err != nil {
		fmt.Println(err)
		return
	}
	// 获取解析出来的kv ，根据k获取值
	name := r.Form.Get("name")
	password := r.Form.Get("password")
	log.Println("username:", name, "@", "password:", password)
	if _, ok := Users[name]; ok {
		auser := Users[name]

		if password == auser.Password {
			w.Write([]byte("ok"))
		} else {
			//状态码引起跨域失败问题。先不纠结。直接去掉
			//w.WriteHeader(403)
			w.Write([]byte("error"))
		}
	} else {
		// 用户不存在，返回用户不存在。
		//状态码引起跨域失败问题。先不纠结。直接去掉
		//w.WriteHeader(404)
		w.Write([]byte("user is not exsit."))
		return
	}
}

func GETUsrInfo(w http.ResponseWriter, r *http.Request) {
	CrossDomain(w, r)
	// 解析url
	err := r.ParseForm()
	if err != nil {
		fmt.Println(err)
		return
	}
	// 获取解析出来的kv ，根据k获取值
	name := r.Form.Get("name")
	if name == "" {
		fmt.Println("args err： name is none")
		w.Write([]byte("please give name to serarch user info."))
		return
	}
	// 判断用户是否存在，用户存在返回用户信息
	if _, ok := Users[name]; ok {
		auser := Users[name]
		auserjson, err := json.Marshal(auser)
		if err != nil {
			fmt.Println(err)
		}
		w.Write(auserjson)
		return
	} else {
		// 用户不存在，返回用户不存在。
		w.Write([]byte("user is not exsit."))
		return
	}
}

func SETUserInfo_urlargs(w http.ResponseWriter, r *http.Request) {
	CrossDomain(w, r)
	err := r.ParseForm()
	if err != nil {
		fmt.Println(err)
		w.Write([]byte("request url args error"))
		return
	}
	auser := AuthUser{}
	auser.Name = r.Form.Get("name")
	auser.Password = r.Form.Get("password")
	Users[auser.Name] = auser
	w.Write([]byte("user set is ok"))
}

//post kv
func SETUserInfo_bodykv(w http.ResponseWriter, r *http.Request) {
	CrossDomain(w, r)
	auser := AuthUser{}
	// 解析post  form-data格式数据。
	auser.Name = r.PostFormValue("name")
	auser.Password = r.PostFormValue("password")

	// 添加用户到map中
	Users[auser.Name] = auser
	w.Write([]byte("user set is ok"))
}

//post json
func SETUserInfo_bodyjson(w http.ResponseWriter, r *http.Request) {
	CrossDomain(w, r)
	userjson, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Println(err)
		return
	}
	auser := AuthUser{}
	// 将json数据解析到结构体实例中
	err = json.Unmarshal(userjson, &auser)
	if err != nil {
		fmt.Println(err)
	}
	Users[auser.Name] = auser
	w.Write([]byte("user set is ok"))
}

func CrossDomain(w http.ResponseWriter, r *http.Request) http.ResponseWriter {
	log.Println("request domain ", r.Host, "URL: ", r.URL)
	w.Header().Set("Access-Control-Allow-Origin", "*")                                                                                              //允许访问所有域
	w.Header().Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Connection, User-Agent, Cookie,Action, Module") //header的类型
	w.Header().Set("content-type", "application/json")                                                                                              //返回数据格式是json
	//header("Access-Control-Allow-Credentials : true");
	w.Header().Add("Access-Control-Allow-Credentials", "true")
	return w
}